<?php

namespace Plugins\IMApi;

use App\Util\TerminalOutput;
use Hyperf\Server\Server;

class Install
{
    public static function run(): void
    {
        // 安装时需要的额外操作
        $configStr = <<<CON
                // websocket 服务配置
                [
                    'name' =>  \\Hyperf\\Support\\env('WEBSOCKET_SERVER_NAME', 'ws'),
                    'type' => Server::SERVER_WEBSOCKET,
                    'host' => '0.0.0.0',
                    'port' =>  (int)\\Hyperf\\Support\\env('WEBSOCKET_SERVER_PORT', 9502),
                    'sock_type' => SWOOLE_SOCK_TCP,
                    'callbacks' => [
                        Event::ON_HAND_SHAKE => [Hyperf\\WebSocketServer\\Server::class, 'onHandShake'],
                        Event::ON_MESSAGE => [Hyperf\\WebSocketServer\\Server::class, 'onMessage'],
                        Event::ON_CLOSE => [Hyperf\\WebSocketServer\\Server::class, 'onClose'],
                    ],
                ],
        CON;

        $serverPath = BASE_PATH . '/config/autoload/server.php';
        $serverConfig = include $serverPath;
        $serverContent = file_get_contents($serverPath);
        if (in_array(Server::SERVER_WEBSOCKET, array_column($serverConfig['servers'], 'type'))){
            TerminalOutput::error('已存在websocket server配置');
        }else{
            $serverNewContent = preg_replace("/^\s*#server\..+$/m", "$configStr\n$0", $serverContent);

            if (file_put_contents($serverPath, $serverNewContent)) {
                TerminalOutput::success("server 配置写入成功");
            }else{
                TerminalOutput::error("server 配置写入失败");
            }
        }

        $routePath = BASE_PATH . '/config/routes.php';
        $routeContent = file_get_contents($routePath);

        if (str_contains($routeContent, 'WebSocketController')) {
            TerminalOutput::error('已存在websocket 路由配置');
        }else{
            $routeContent .= <<<COD
            // websocket 服务路由配置
            Router::addServer('ws', function () {
                Router::get('/', 'Plugins\IMApi\WebSocketController');
            });
            COD;
            if (file_put_contents($routePath, $routeContent)) {
                TerminalOutput::success("路由配置写入成功");
            }else{
                TerminalOutput::error("路由配置写入失败");
            }
        }

        // 安装时需要的额外操作
        $dependenciesPath = BASE_PATH . '/config/autoload/dependencies.php';
        $dependencies = include $dependenciesPath;
        $interfaces = array_keys($dependencies);
        $replace = [];
        if (!in_array(WebSocketMessageHandlerInterface::class, $interfaces)) {
            $replace[] = <<<DEP
                // websocket 消息处理
                Plugins\IMApi\WebSocketMessageHandlerInterface::class => Plugins\IMApi\Service\MessageService::class,
            DEP;
        }
        if ($replace) {
            $dependencies = file_get_contents($dependenciesPath);
            $replace = implode("\n", $replace);
            $dependencies = preg_replace("/];\s*$/", <<<DEP
            $replace
            ];
            DEP
                , $dependencies);
            $res = file_put_contents($dependenciesPath, $dependencies);
            if ($res) {
                TerminalOutput::success("dependencies.php 配置写入成功");
            }else{
                TerminalOutput::error('dependencies.php 配置写入失败，请手动配置');
            }
        }else{
            TerminalOutput::error("dependencies.php 已存在 websocket 消息处理配置");
        }


        $middlewarePath = BASE_PATH . '/config/autoload/middlewares.php';
        $middleware = include $middlewarePath;
        if (!isset($middleware['ws'])) {
            $replace = <<<DEP
                'ws' => [
                    \App\Middlewares\CrossDomainMiddleware::class,
                    \Plugins\IMApi\Middlewares\AuthMiddleware::class,
                ],
            DEP;
            $middleware = file_get_contents($middlewarePath);
            $middleware = preg_replace("/];\s*$/", <<<DEP
            $replace
            ];
            DEP, $middleware);
            $res = file_put_contents($middlewarePath, $middleware);
            if ($res) {
                TerminalOutput::success("middlewares.php 配置写入成功");
            }else{
                TerminalOutput::error('middlewares.php 配置写入失败，请手动配置');
            }
        }else{
            TerminalOutput::error("middlewares.php 已存在 websocket 认证中间件配置");
        }


        TerminalOutput::purple('=================================== WebSocket Server ====================================');
        TerminalOutput::info("== 认证方式为url地址token字段携带jwt信息，例：  ws://127.0.0.1:9502?token=121111");
        TerminalOutput::info("== 认证信息默认识别 user_id 字段， 如有调整请自行修改 WebSocketController::onOpen 的代码");
        TerminalOutput::info("== 修改 dependencies.php 中的配置为自定义消息处理逻辑");
        TerminalOutput::info("== 心跳监听消息为: ping ");
        TerminalOutput::info("== 默认消息处理说明：");
        TerminalOutput::info("== 消息内容为：s(user=1) hello 时，发送给用户ID为1的消息为：hello");
        TerminalOutput::info("== 消息内容为：s(fd=1) hello 时，发送给fd为1的消息为：hello");
        TerminalOutput::info("== 消息内容为：s(room=1) hello 时，发送给房间为1的消息为：hello");
        TerminalOutput::info("== 消息内容为：h(room=1&user=1) 时，用户ID1加入房间ID1");
        TerminalOutput::info("== 消息内容为：h(room=1^user=1) 时，用户ID1退出房间ID1");
        TerminalOutput::purple('=========================================================================================');
    }
}